home *** CD-ROM | disk | FTP | other *** search
/ Aminet 25 / Aminet 25 (1998)(GTI - Schatztruhe)[!][Jun 1998].iso / Aminet / dev / debug / Blowup.lha / source / main.c < prev    next >
C/C++ Source or Header  |  1998-04-18  |  8KB  |  415 lines

  1. /*
  2.  * $Id: main.c 1.6 1998/04/18 15:44:40 olsen Exp olsen $
  3.  *
  4.  * :ts=4
  5.  *
  6.  * Blowup -- Catches and displays task errors
  7.  *
  8.  * Written by Olaf `Olsen' Barthel <olsen@sourcery.han.de>
  9.  * Public Domain
  10.  */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "global.h"
  14. #endif    /* _GLOBAL_H */
  15.  
  16. /******************************************************************************/
  17.  
  18. #include "Blowup_rev.h"
  19.  
  20. /******************************************************************************/
  21.  
  22. #include "blowupsemaphore.h"
  23.  
  24. /******************************************************************************/
  25.  
  26. const STRPTR VersTag = VERSTAG;
  27.  
  28. /******************************************************************************/
  29.  
  30. STATIC BOOL ShowBannerMessage = TRUE;
  31.  
  32. /******************************************************************************/
  33.  
  34. STATIC struct BlowupSemaphore *    BlowupSemaphore;
  35. STATIC BOOL                        BlowupSemaphoreCreated;
  36.  
  37. /******************************************************************************/
  38.  
  39. STATIC struct BlowupSemaphore *
  40. FindBlowupSemaphore(VOID)
  41. {
  42.     struct BlowupSemaphore * bs;
  43.  
  44.     /* look for the semaphore; this call must be made under Forbid() */
  45.     bs = (struct BlowupSemaphore *)FindSemaphore(BLOWUPSEMAPHORENAME);
  46.  
  47.     return(bs);
  48. }
  49.  
  50. STATIC VOID
  51. DeleteBlowupSemaphore(struct BlowupSemaphore * bs)
  52. {
  53.     if(bs != NULL)
  54.     {
  55.         /* gain exclusive access to the semaphore and remove it */
  56.         ObtainSemaphore((struct SignalSemaphore *)bs);
  57.         RemSemaphore((struct SignalSemaphore *)bs);
  58.         ReleaseSemaphore((struct SignalSemaphore *)bs);
  59.  
  60.         /* release the memory allocated for the semaphore */
  61.         FreeMem(bs,sizeof(*bs));
  62.     }
  63. }
  64.  
  65. STATIC struct BlowupSemaphore *
  66. CreateBlowupSemaphore(VOID)
  67. {
  68.     struct BlowupSemaphore * bs;
  69.  
  70.     /* allocate memory for the semaphore and initialize */
  71.     bs = AllocMem(sizeof(*bs),MEMF_ANY|MEMF_PUBLIC|MEMF_CLEAR);
  72.     if(bs != NULL)
  73.     {
  74.         bs->bs_SignalSemaphore.ss_Link.ln_Name    = bs->bs_SemaphoreName;
  75.         bs->bs_SignalSemaphore.ss_Link.ln_Pri    = 1;
  76.  
  77.         bs->bs_Version = BLOWUPSEMAPHOREVERSION;
  78.  
  79.         strcpy(bs->bs_SemaphoreName,BLOWUPSEMAPHORENAME);
  80.  
  81.         bs->bs_Owner        = FindTask(NULL);
  82.         bs->bs_ARegCheck    = &ARegCheck;
  83.         bs->bs_DRegCheck    = &DRegCheck;
  84.         bs->bs_StackCheck    = &StackCheck;
  85.         bs->bs_StackLines    = &StackLines;
  86.  
  87.         /* add the semaphore to the public list */
  88.         AddSemaphore((struct SignalSemaphore *)bs);
  89.     }
  90.  
  91.     return(bs);
  92. }
  93.  
  94. /******************************************************************************/
  95.  
  96. STATIC VOID
  97. Cleanup(VOID)
  98. {
  99.     /* delete the semaphore, if we created it */
  100.     if(BlowupSemaphoreCreated)
  101.     {
  102.         DeleteBlowupSemaphore(BlowupSemaphore);
  103.         BlowupSemaphore = NULL;
  104.     }
  105.  
  106.     /* release the semaphore; this is done only if we did
  107.      * not create the semaphore ourselves
  108.      */
  109.     if(BlowupSemaphore != NULL)
  110.     {
  111.         ReleaseSemaphore((struct SignalSemaphore *)BlowupSemaphore);
  112.         BlowupSemaphore = NULL;
  113.     }
  114.  
  115.     /* shut down the timer */
  116.     DeleteTimer();
  117.  
  118.     /* close intuition.library */
  119.     if(IntuitionBase != NULL)
  120.     {
  121.         CloseLibrary(IntuitionBase);
  122.         IntuitionBase = NULL;
  123.     }
  124.  
  125.     /* close utility.library, if this is necessary */
  126.     #if !defined(__SASC) || defined(_M68020)
  127.     {
  128.         if(UtilityBase != NULL)
  129.         {
  130.             CloseLibrary(UtilityBase);
  131.             UtilityBase = NULL;
  132.         }
  133.     }
  134.     #endif
  135. }
  136.  
  137. STATIC BOOL
  138. Setup(VOID)
  139. {
  140.     LONG error = OK;
  141.     int i;
  142.  
  143.     /* Kickstart 2.04 or higher required */
  144.     if(SysBase->LibNode.lib_Version < 37)
  145.     {
  146.         const STRPTR message = "This program requires Kickstart 2.04 or better.\n";
  147.  
  148.         Write(Output(),message,strlen(message));
  149.         return(FAILURE);
  150.     }
  151.  
  152.     /* determine the program name */
  153.     StrcpyN(sizeof(ProgramName),ProgramName,VERS);
  154.  
  155.     for(i = strlen(ProgramName) - 1 ; i >= 0 ; i--)
  156.     {
  157.         if(ProgramName[i] == ' ')
  158.         {
  159.             ProgramName[i] = '\0';
  160.             break;
  161.         }
  162.     }
  163.  
  164.     /* set up the busy semaphore */
  165.     InitSemaphore(&BusySemaphore);
  166.  
  167.     /* open intuition.library */
  168.     IntuitionBase = OpenLibrary("intuition.library",37);
  169.     if(IntuitionBase == NULL)
  170.     {
  171.         Printf("%s: Could not open intuition.library V37.\n",ProgramName);
  172.         return(FAILURE);
  173.     }
  174.  
  175.     /* open utility.library, if this is necessary */
  176.     #if !defined(__SASC) || defined(_M68020)
  177.     {
  178.         UtilityBase = OpenLibrary("utility.library",37);
  179.         if(UtilityBase == NULL)
  180.         {
  181.             Printf("%s: Could not open utility.library V37.\n",ProgramName);
  182.             return(FAILURE);
  183.         }
  184.     }
  185.     #endif
  186.  
  187.     /* allocate the timer data */
  188.     if(CreateTimer() == -1)
  189.     {
  190.         Printf("%s: Could not create timer.\n",ProgramName);
  191.         return(FAILURE);
  192.     }
  193.  
  194.     /* initialize default options */
  195.     DRegCheck    = FALSE;
  196.     ARegCheck    = FALSE;
  197.     StackCheck    = FALSE;
  198.     StackLines    = 2;
  199.  
  200.     /* rendezvous with the global semaphore or create it */
  201.     Forbid();
  202.  
  203.     BlowupSemaphore = FindBlowupSemaphore();
  204.     if(BlowupSemaphore != NULL)
  205.     {
  206.         ObtainSemaphore((struct SignalSemaphore *)BlowupSemaphore);
  207.     }
  208.     else
  209.     {
  210.         BlowupSemaphore = CreateBlowupSemaphore();
  211.         if(BlowupSemaphore != NULL)
  212.         {
  213.             BlowupSemaphoreCreated = TRUE;
  214.         }
  215.         else
  216.         {
  217.             error = ERROR_NO_FREE_STORE;
  218.         }
  219.     }
  220.  
  221.     Permit();
  222.  
  223.     if(error == OK)
  224.     {
  225.         struct RDArgs * rda;
  226.  
  227.         /* these are the command line parameters, later
  228.          * filled in by ReadArgs() below
  229.          */
  230.         struct
  231.         {
  232.             SWITCH    Off;
  233.             SWITCH    Parallel;
  234.             SWITCH    NoBanner;
  235.             SWITCH    DRegCheck;
  236.             SWITCH    NoDRegCheck;
  237.             SWITCH    ARegCheck;
  238.             SWITCH    NoARegCheck;
  239.             SWITCH    StackCheck;
  240.             SWITCH    NoStackCheck;
  241.             NUMBER    StackLines;
  242.         } params;
  243.     
  244.         /* this is the command template, as required by ReadArgs() below;
  245.          * its contents must match the "params" data structure above
  246.          */
  247.         const STRPTR cmdTemplate =
  248.             "QUIT=OFF/S,"
  249.             "PARALLEL/S,"
  250.             "QUIET=NOBANNER/S,"
  251.             "DREGCHECK/S,"
  252.             "NODREGCHECK/S,"
  253.             "AREGCHECK/S,"
  254.             "NOAREGCHECK/S,"
  255.             "STACKCHECK/S,"
  256.             "NOSTACKCHECK/S,"
  257.             "STACKLINES/K/N";
  258.  
  259.         memset(¶ms,0,sizeof(params));
  260.  
  261.         /* read the command line parameters */
  262.         rda = ReadArgs((STRPTR)cmdTemplate,(LONG *)¶ms,NULL);
  263.         if(rda != NULL)
  264.         {
  265.             struct BlowupSemaphore * bs = BlowupSemaphore;
  266.  
  267.             /* enable data register check? */
  268.             if(params.DRegCheck)
  269.             {
  270.                 (*bs->bs_DRegCheck) = TRUE;
  271.             }
  272.  
  273.             /* disable data register check? */
  274.             if(params.NoDRegCheck)
  275.             {
  276.                 (*bs->bs_DRegCheck) = FALSE;
  277.             }
  278.  
  279.             /* enable address register check? */
  280.             if(params.ARegCheck)
  281.             {
  282.                 (*bs->bs_ARegCheck) = TRUE;
  283.             }
  284.  
  285.             /* disable address register check? */
  286.             if(params.NoARegCheck)
  287.             {
  288.                 (*bs->bs_ARegCheck) = FALSE;
  289.             }
  290.  
  291.             /* enable stack check? */
  292.             if(params.StackCheck)
  293.             {
  294.                 (*bs->bs_StackCheck) = TRUE;
  295.             }
  296.  
  297.             /* disable stack check? */
  298.             if(params.NoStackCheck)
  299.             {
  300.                 (*bs->bs_StackCheck) = FALSE;
  301.             }
  302.  
  303.             /* set the number of stack lines to display? */
  304.             if(params.StackLines != NULL)
  305.             {
  306.                 LONG value;
  307.  
  308.                 value = (*params.StackLines);
  309.                 if(value < 0)
  310.                     value = 0;
  311.  
  312.                 (*bs->bs_StackLines) = value;
  313.             }
  314.  
  315.             /* do not show the banner message? */
  316.             if(params.NoBanner)
  317.             {
  318.                 ShowBannerMessage = FALSE;
  319.             }
  320.  
  321.             /* enable parallel port output? */
  322.             if(params.Parallel)
  323.             {
  324.                 ChooseParallelOutput();
  325.             }
  326.  
  327.             /* shut down Blowup? */
  328.             if(params.Off)
  329.             {
  330.                 if(NOT BlowupSemaphoreCreated)
  331.                 {
  332.                     Signal(bs->bs_Owner,SIG_Stop);
  333.                 }
  334.             }
  335.  
  336.             FreeArgs(rda);
  337.         }
  338.         else
  339.         {
  340.             error = IoErr();
  341.         }
  342.     }
  343.  
  344.     if(error == OK)
  345.     {
  346.         return(SUCCESS);
  347.     }
  348.     else
  349.     {
  350.         PrintFault(error,ProgramName);
  351.  
  352.         return(FAILURE);
  353.     }
  354. }
  355.  
  356. /******************************************************************************/
  357.  
  358. int
  359. main(
  360.     int        argc,
  361.     char **    argv)
  362. {
  363.     int result = RETURN_FAIL;
  364.  
  365.     /* set up all the data we need */
  366.     if(Setup())
  367.     {
  368.         result = RETURN_OK;
  369.  
  370.         /* do something useful if we are the owner of the semaphore */
  371.         if(BlowupSemaphoreCreated)
  372.         {
  373.             BOOL done;
  374.         
  375.             /* show the welcome message */
  376.             if(ShowBannerMessage)
  377.             {
  378.                 DPrintf("%s -- Catches and displays task errors\n",ProgramName);
  379.                 DPrintf("Written by Olaf `Olsen' Barthel <olsen@sourcery.han.de>\n");
  380.                 DPrintf("Public Domain\n");
  381.             }
  382.     
  383.             Forbid();
  384.  
  385.             /* plant the monitoring patches */
  386.             AddPatches();
  387.     
  388.             done = FALSE;
  389.             do
  390.             {
  391.                 /* wait for something to happen */
  392.                 if(FLAG_IS_SET(Wait(SIG_Stop),SIG_Stop))
  393.                 {
  394.                     done = TRUE;
  395.  
  396.                     /* wait until it is safe to quit */
  397.                     ObtainSemaphore(&BusySemaphore);
  398.  
  399.                     DPrintf("%s terminated.\n",ProgramName);
  400.                 }
  401.             }
  402.             while(NOT done);
  403.     
  404.             /* remove the patches again */
  405.             RemovePatches();
  406.  
  407.             Permit();
  408.         }
  409.     }
  410.  
  411.     Cleanup();
  412.  
  413.     return(result);
  414. }
  415.